package com.jblv.frame.config;

import org.springframework.beans.factory.annotation.Value;

import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.concurrent.ConcurrentHashMap;
import java.util.Map;

/**
 * @author happyonion.yangtao
 * @version 1.0
 * @title RefreshScopeBeanHolder
 * @projectName jblv-frame
 * @packageName com.jblv.frame.config
 * @description TODO
 * @date Create at 2020/9/7 17:22
 * @since jdk1.8
 */
public class RefreshScopeBeanHolder {


    private static ConcurrentHashMap<Object, Map<String, Field>> refreshScopeBeanMap;
    private static ConcurrentHashMap<Object, Boolean> scopeBeanMap;

    public static void putScopeBean(final String beanName) {
        RefreshScopeBeanHolder.scopeBeanMap.put(beanName, true);
    }

    public static boolean checkScopeBean(final String beanName) {
        return RefreshScopeBeanHolder.scopeBeanMap.get(beanName) != null;
    }

    public static void put(final Object bean, final Value value, final Field declaredField) {
        Map<String, Field> fieldMap = RefreshScopeBeanHolder.refreshScopeBeanMap.get(bean);
        if (fieldMap == null) {
            fieldMap = new HashMap<String, Field>();
            RefreshScopeBeanHolder.refreshScopeBeanMap.put(bean, fieldMap);
        }
        String key = value.value().trim();
        if (key.startsWith("${") && key.endsWith("}")) {
            key = key.replace("${", "").replace("}", "");
            key = key.split(":")[0];
            fieldMap.put(key.trim(), declaredField);
        }
    }

    public static void refresh(final String key, final String value) throws IllegalAccessException {
        for (final Object bean : RefreshScopeBeanHolder.refreshScopeBeanMap.keySet()) {
            final Map<String, Field> fieldMap = RefreshScopeBeanHolder.refreshScopeBeanMap.get(bean);
            if (fieldMap == null) {
                continue;
            }
            final Field declaredField = fieldMap.get(key);
            if (declaredField == null) {
                continue;
            }
            declaredField.set(bean, value);
        }
    }

}
